from fastapi import APIRouter, HTTPException, Query, Path
from typing import List, Optional, Literal
from pydantic import BaseModel, Field
from app.model.model_learn import Learn, LearnCreate, LearnUpdate, LearnResponse, LearnWithLessonsResponse

router = APIRouter(prefix="/learn", tags=["Learn"])

class LessonAssociationRequest(BaseModel):
    lesson_id: int = Field(..., description="要关联的课程ID")

class PaginatedLearnResponse(BaseModel):
    """分页学习课程响应模型"""
    data: List[LearnResponse] = Field(..., description="学习课程列表")
    total: int = Field(..., description="总数量")
    page_num: int = Field(..., description="当前页码")
    page_size: int = Field(..., description="每页数量")
    total_pages: int = Field(..., description="总页数")

@router.post("/", response_model=LearnResponse, summary="创建学习课程")
async def create_learn(learn_data: LearnCreate):
    """
    创建新的学习课程
    """
    try:
        learn = Learn(
            learnId=learn_data.learnId,
            process=learn_data.process,
            procedure=learn_data.procedure,
            subProcedure=learn_data.subProcedure,
            standardSolution=learn_data.standardSolution,
            standardName=learn_data.standardName,
            system=learn_data.system,
            platform=learn_data.platform,
            lineType=learn_data.lineType,
            failureMode=learn_data.failureMode,
            schematicDiagram=learn_data.schematicDiagram,
            fixCateory=learn_data.fixCateory,
            standardFileNo=learn_data.standardFileNo,
            controlStatus=learn_data.controlStatus,
            landedStatus=learn_data.landedStatus,
            subSystemRelatedItems=learn_data.subSystemRelatedItems,
            creatorId=learn_data.creatorId,
            updaterId=learn_data.updaterId
        )
        learn_id = learn.save()
        
        # 重新获取完整数据
        created_learn = Learn.get_by_id(learn_id)
        return created_learn.to_dict()
    except Exception as e:
        raise HTTPException(status_code=400, detail=f"创建学习课程失败: {str(e)}")

@router.get("/", response_model=PaginatedLearnResponse, summary="获取所有学习课程")
async def get_all_learns(
    page_num: int = Query(1, ge=1, description="页码，从1开始"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量，默认20"),
    search: Optional[str] = Query(None, description="按LearnID搜索"),
    control_status: Optional[str] = Query(None, description="按受控状态筛选")
):
    """
    获取所有学习课程，支持分页、搜索和筛选
    """
    try:
        # 计算偏移量
        offset = (page_num - 1) * page_size
        
        # 获取数据
        if search:
            learns = Learn.search_by_learn_id(search)
            total = len(learns)
            # 手动分页
            learns = learns[offset:offset + page_size]
        elif control_status:
            learns = Learn.get_by_control_status(control_status)
            total = len(learns)
            # 手动分页
            learns = learns[offset:offset + page_size]
        else:
            # 获取总数
            total = Learn.get_count()
            # 获取分页数据
            learns = Learn.get_all(page_size, offset)
        
        # 计算总页数
        total_pages = (total + page_size - 1) // page_size
        
        return PaginatedLearnResponse(
            data=[learn.to_dict() for learn in learns],
            total=total,
            page_num=page_num,
            page_size=page_size,
            total_pages=total_pages
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取学习课程失败: {str(e)}")

@router.get("/{learn_id}", response_model=LearnWithLessonsResponse, summary="获取单个学习课程")
async def get_learn_by_id(learn_id: str = Path(..., description="学习课程ID或LearnID")):
    """
    根据ID或LearnID获取单个学习课程及其关联的课程
    支持整数ID（如：1）或LearnID字符串（如：Learn-19930901-v868）
    """
    try:
        # 尝试判断是整数ID还是LearnID字符串
        if learn_id.isdigit():
            # 整数ID
            learn = Learn.get_by_id(int(learn_id))
        else:
            # LearnID字符串
            learn = Learn.get_by_learn_id(learn_id)
        
        if not learn:
            raise HTTPException(status_code=404, detail="学习课程不存在")
        
        result = learn.to_dict()
        result['lessons'] = learn.get_lessons()
        return result
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取学习课程失败: {str(e)}")

@router.put("/{learn_id}", response_model=LearnResponse, summary="更新学习课程")
async def update_learn(
    learn_id: str = Path(..., description="学习课程ID或LearnID"),
    learn_data: LearnUpdate = None
):
    """
    更新学习课程信息
    支持整数ID（如：1）或LearnID字符串（如：Learn-19930901-v868）
    """
    try:
        # 尝试判断是整数ID还是LearnID字符串
        if learn_id.isdigit():
            # 整数ID
            learn = Learn.get_by_id(int(learn_id))
        else:
            # LearnID字符串
            learn = Learn.get_by_learn_id(learn_id)
        
        if not learn:
            raise HTTPException(status_code=404, detail="学习课程不存在")
        
        # 更新字段
        if learn_data.learnId is not None:
            learn.learnId = learn_data.learnId
        if learn_data.process is not None:
            learn.process = learn_data.process
        if learn_data.procedure is not None:
            learn.procedure = learn_data.procedure
        if learn_data.subProcedure is not None:
            learn.subProcedure = learn_data.subProcedure
        if learn_data.standardSolution is not None:
            learn.standardSolution = learn_data.standardSolution
        if learn_data.standardName is not None:
            learn.standardName = learn_data.standardName
        if learn_data.system is not None:
            learn.system = learn_data.system
        if learn_data.platform is not None:
            learn.platform = learn_data.platform
        if learn_data.lineType is not None:
            learn.lineType = learn_data.lineType
        if learn_data.failureMode is not None:
            learn.failureMode = learn_data.failureMode
        if learn_data.schematicDiagram is not None:
            learn.schematicDiagram = learn_data.schematicDiagram
        if learn_data.fixCateory is not None:
            learn.fixCateory = learn_data.fixCateory
        if learn_data.standardFileNo is not None:
            learn.standardFileNo = learn_data.standardFileNo
        if learn_data.controlStatus is not None:
            learn.controlStatus = learn_data.controlStatus
        if learn_data.landedStatus is not None:
            learn.landedStatus = learn_data.landedStatus
        if learn_data.subSystemRelatedItems is not None:
            learn.subSystemRelatedItems = learn_data.subSystemRelatedItems
        if learn_data.updaterId is not None:
            learn.updaterId = learn_data.updaterId
        
        learn.save()
        return learn.to_dict()
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=400, detail=f"更新学习课程失败: {str(e)}")

@router.delete("/{learn_id}", summary="删除学习课程")
async def delete_learn(learn_id: str = Path(..., description="学习课程ID或LearnID")):
    """
    删除学习课程及其所有关联关系
    支持整数ID（如：1）或LearnID字符串（如：Learn-19930901-v868）
    """
    try:
        # 尝试判断是整数ID还是LearnID字符串
        if learn_id.isdigit():
            # 整数ID
            learn = Learn.get_by_id(int(learn_id))
        else:
            # LearnID字符串
            learn = Learn.get_by_learn_id(learn_id)
        
        if not learn:
            raise HTTPException(status_code=404, detail="学习课程不存在")
        
        success = learn.delete()
        if success:
            return {"message": "学习课程删除成功"}
        else:
            raise HTTPException(status_code=500, detail="删除学习课程失败")
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"删除学习课程失败: {str(e)}")

@router.post("/{learn_id}/lessons", summary="为学习课程添加课程")
async def add_lesson_to_learn(
    learn_id: str = Path(..., description="学习课程ID或LearnID"),
    lesson_data: LessonAssociationRequest = None
):
    """
    为学习课程添加关联的课程
    支持整数ID（如：1）或LearnID字符串（如：Learn-19930901-v868）
    """
    try:
        # 尝试判断是整数ID还是LearnID字符串
        if learn_id.isdigit():
            # 整数ID
            learn = Learn.get_by_id(int(learn_id))
        else:
            # LearnID字符串
            learn = Learn.get_by_learn_id(learn_id)
        
        if not learn:
            raise HTTPException(status_code=404, detail="学习课程不存在")
        
        # 检查课程是否存在
        from app.model.model_lesson import Lesson
        lesson = Lesson.get_by_id(lesson_data.lesson_id)
        if not lesson:
            raise HTTPException(status_code=404, detail="课程不存在")
        
        success = learn.add_lesson(lesson_data.lesson_id)
        if success:
            return {"message": "课程关联成功"}
        else:
            return {"message": "课程已关联或关联失败"}
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=400, detail=f"添加课程关联失败: {str(e)}")

@router.delete("/{learn_id}/lessons/{lesson_id}", summary="移除学习课程的课程关联")
async def remove_lesson_from_learn(
    learn_id: str = Path(..., description="学习课程ID或LearnID"),
    lesson_id: int = Path(..., description="课程ID")
):
    """
    移除学习课程与课程的关联关系
    支持整数ID（如：1）或LearnID字符串（如：Learn-19930901-v868）
    """
    try:
        # 尝试判断是整数ID还是LearnID字符串
        if learn_id.isdigit():
            # 整数ID
            learn = Learn.get_by_id(int(learn_id))
        else:
            # LearnID字符串
            learn = Learn.get_by_learn_id(learn_id)
        
        if not learn:
            raise HTTPException(status_code=404, detail="学习课程不存在")
        
        success = learn.remove_lesson(lesson_id)
        if success:
            return {"message": "课程关联移除成功"}
        else:
            return {"message": "课程关联不存在或移除失败"}
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=400, detail=f"移除课程关联失败: {str(e)}")

@router.get("/{learn_id}/lessons", response_model=List[dict], summary="获取学习课程的关联课程")
async def get_learn_lessons(learn_id: str = Path(..., description="学习课程ID或LearnID")):
    """
    获取学习课程关联的所有课程
    支持整数ID（如：1）或LearnID字符串（如：Learn-19930901-v868）
    """
    try:
        # 尝试判断是整数ID还是LearnID字符串
        if learn_id.isdigit():
            # 整数ID
            learn = Learn.get_by_id(int(learn_id))
        else:
            # LearnID字符串
            learn = Learn.get_by_learn_id(learn_id)
        
        if not learn:
            raise HTTPException(status_code=404, detail="学习课程不存在")
        
        lessons = learn.get_lessons()
        return lessons
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取关联课程失败: {str(e)}")

@router.get("/stats/count", summary="获取学习课程统计信息")
async def get_learn_stats():
    """
    获取学习课程统计信息
    """
    try:
        total_count = Learn.get_count()
        return {
            "total_learns": total_count,
            "message": "统计信息获取成功"
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取统计信息失败: {str(e)}")

@router.get("/control-statuses/list", response_model=List[str], summary="获取所有受控状态列表")
async def get_control_status_list():
    """
    获取所有可用的受控状态列表
    """
    try:
        # 从数据库中动态获取所有受控状态
        from app.db.database import db
        query = "SELECT DISTINCT controlStatus FROM learn ORDER BY controlStatus"
        results = db.execute_query(query)
        statuses = [row['controlStatus'] for row in results if row['controlStatus']]
        return statuses if statuses else []
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取受控状态列表失败: {str(e)}")

@router.get("/landed-statuses/list", response_model=List[str], summary="获取所有落地状态列表")
async def get_landed_status_list():
    """
    获取所有可用的落地状态列表
    """
    try:
        # 从数据库中动态获取所有落地状态
        from app.db.database import db
        query = "SELECT DISTINCT landedStatus FROM learn ORDER BY landedStatus"
        results = db.execute_query(query)
        statuses = [row['landedStatus'] for row in results if row['landedStatus']]
        return statuses if statuses else []
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取落地状态列表失败: {str(e)}")
